<script setup lang="ts">
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import localForage from 'localforage';
import { useThemeStore } from '@/store/modules/theme';
import { useSvgIcon } from '@/hooks/common/icon';
import { router } from '@/router';
import {
  deleteTaskDetailApi,
  fetchTaskApi,
  // fetchTaskDetailApi,
  fetchTaskIdsListApi,
  fetchTaskListApi,
  updateTaskApi
} from '@/service/api';

import { useStore } from '../product-center/store';

const store = useStore();

const { SvgIconVNode } = useSvgIcon();

const themeStore = useThemeStore();

// 新增
const addLoading = ref<any>(false);
const handleAdd = async (row?: any) => {
  if (row) {
    router.push(`/product-center?id=${row.id}&detailId=${row.detailId}&videoName=${row.videoName}`);
  } else {
    addLoading.value = true;
    store.createTask();
    setTimeout(() => {
      addLoading.value = false;
      router.push('/product-center');
    }, 10);
  }
};

// 下拉操作
const dropdown = reactive({
  onSelect: (key: string, row: any) => {
    modal.key = key;
    modal.id = row.id;
    if (key === 'rename') {
      console.log('rename');
      modal.inputValue = row.videoName; // 名称赋值
      modal.content = '修改名称';
    }
    if (key === 'delete') {
      modal.content = '确定删除此视频？';
      modal.subContent = '此操作无法撤销';
    }
    modal.visible = true;
  }
});

// 下载 不是导出
const download = async (row: any) => {
  if (!row.url) {
    window.$message?.error('视频地址为空');
    return;
  }
  // 根据视频地址下载视频到本地
  window.$message?.success('下载视频成功');
  // window.$message?.loading('正在下载视频...');
  try {
    const a = document.createElement('a');
    a.href = row.url; // 替换为你的视频链接
    a.download = '下载视频.mp4'; // 可以指定下载文件的名称
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  } catch (error) {
    // console.error('下载视频时出错:', error);
    window.$message?.error('视频下载异常');
  }
};

// 删除重命名
const modal = reactive({
  visible: false,
  key: '',
  content: '',
  subContent: '',
  id: '',
  inputValue: '',
  submit: async () => {
    if (modal.key === 'rename') {
      const { data } = await updateTaskApi({
        id: modal.id,
        videoName: modal.inputValue
      });
      if (data) {
        window.$message?.success('操作成功');
        getList();
      }
    }
    if (modal.key === 'delete') {
      // 接口
      const { data } = await deleteTaskDetailApi(modal.id);
      if (data) {
        window.$message?.success('删除成功');
        getList();
      }
    }
    modal.visible = false;
  },
  reset: () => {
    modal.id = '';
    modal.key = '';
    modal.content = '';
    modal.subContent = '';
    modal.inputValue = '';
    preview.visible = false;
  }
});

// 预览
const preview = reactive<any>({
  visible: false,
  row: {},
  show: async (row: any) => {
    console.log('object');
    const isok = isDone(row.videoStatus);
    const draft = isDraft(row.videoStatus);
    if (draft) {
      // 草稿
      handleAdd(row);
      return;
    }
    if (!isok) {
      return;
    }

    const { data } = await fetchTaskApi(row.id);
    console.log(data);
    if (data) {
      preview.row = {
        ...row,
        ...data
      };
      preview.visible = true;
    }
  },
  reset: () => {
    preview.row = {};
  }
});

// 主题颜色类名创建
const cardClass = () => {
  const dark = 'hover:bg-content_bg hover:!border-#2E3246';
  const light = 'hover:bg-white';
  return themeStore.darkMode ? dark : light;
};

// 获取列表
const list = ref<any[]>([]);
// 添加分页相关的响应式数据
const pagination = reactive({
  page: 1,
  pageSize: 10,
  total: 0,
  onChange: (page: number) => {
    pagination.page = page;
    getList(page, pagination.pageSize);
  },
  onUpdatePageSize: (pageSize: number) => {
    pagination.pageSize = pageSize;
    pagination.page = 1;
    getList(pagination.page, pageSize);
  }
});

const loading = ref(false);

async function getList(page?: number, pageSize?: number) {
  loading.value = true;
  try {
    const params = {
      page: page || pagination.page,
      pageSize: pageSize || pagination.pageSize
    };
    const { data } = await fetchTaskListApi(params);
    if (data) {
      // list.value = data?.records || [];
      // console.log('list.value: ', list.value);

      const creatingList = (await localForage.getItem<{ id: number; eat: number }[]>('creatingList')) || [];

      const records = data?.records || [];

      list.value = records.map((i: any) => {
        const { eat } = creatingList.find(item => item.id === i.id) || { eat: 140 };

        const usedTime = Date.now() - new Date(i.createTime).getTime();

        const rate = (usedTime > eat * 1000 ? 98 + Math.random() : (usedTime / (eat * 1000)) * 100 * 0.98).toFixed(2);

        return { ...i, eat, rate, usedTime };
      });
      // list.value
      console.log('list.value: ', list.value);

      pagination.total = data?.total || 0;
      rendingIds.value = data?.records.filter((v: any) => isLoading(v.videoStatus)).map((v: any) => v.id);

      // console.log('rendingIds.value: ', rendingIds.value);
    }
  } catch (error) {
    window.$message?.error('获取列表失败');
  } finally {
    loading.value = false;
  }
}

// 轮询
const rendingIds = ref<any[]>([]); // 需要轮询的任务id
async function pollList(ids: any[]) {
  try {
    const { data } = await fetchTaskIdsListApi(ids);

    const creatingList = (await localForage.getItem<{ id: number; eat: number }[]>('creatingList')) || [];
    console.log('creatingList: ', creatingList);

    const map = data.map((i: any) => {
      const { eat } = creatingList.find(item => item.id === i.id) || { eat: 140 };

      const usedTime = Date.now() - new Date(i.createTime).getTime();

      const rate = (usedTime > eat * 1000 ? 98 + Math.random() : (usedTime / (eat * 1000)) * 100 * 0.98).toFixed(2);

      return { ...i, eat, rate };
    });

    await localForage.setItem('creatingList', map);

    if (map) {
      list.value = list.value.map(item => {
        const find = map.find((i: any) => i.id === item.id);
        console.log('find: ', find);

        return { ...item, ...find };
      });
    }

    if (data) {
      // 列表对比，赋值
      const finishList = data.filter((v: any) => !isLoading(v.videoStatus));
      if (finishList.length > 0) {
        finishList.forEach((v: any) => {
          const find = list.value.find((vv: any) => vv.id === v.id);
          if (find) {
            list.value.splice(list.value.indexOf(find), 1, v);
            rendingIds.value.splice(rendingIds.value.indexOf(v.id), 1);
          }
        });
      }
      console.log('🚀 ~ finishList.forEach ~ rendingIds.value:', rendingIds.value);
    }
  } catch (_e) {
    clearTimer();
  }
}

const timer = ref<ReturnType<typeof setInterval> | null>(null);
const startTimer = async () => {
  if (timer.value) return;
  timer.value = setInterval(() => {
    pollList(rendingIds.value);
  }, 2000);
};
const clearTimer = () => {
  clearInterval(timer.value!);
  timer.value = null;
};

watch(
  () => rendingIds.value.length,
  newValue => {
    if (newValue > 0) {
      startTimer();
    } else {
      // 有结果了
      clearTimer();
    }
    getList();
  }
);

onUnmounted(() => {
  clearTimer();
});

// 初始化加载
onMounted(() => {
  getList();
});
const isLoading = (status: number) => {
  return status === 1;
};
const isDone = (status: number) => {
  return status === 2;
};
const isDraft = (status: number) => {
  return status === 0;
};

const getDropdownOptions = () => {
  return [
    {
      label: '重命名',
      key: 'rename',
      // disabled: !isDone(status),
      icon: SvgIconVNode({ icon: 'tabler:pencil-cog', fontSize: 18 })
    },
    {
      label: '删除',
      key: 'delete',
      icon: SvgIconVNode({ icon: 'clarity:trash-line', fontSize: 18 })
    }
  ];
};
</script>

<template>
  <div>
    <header class="page-title">创作中心</header>
    <main>
      <NSpin :show="loading">
        <ul class="list">
          <li class="card create" @click="handleAdd()">
            <div class="card-img-wraper">
              <img v-if="themeStore.darkMode" src="@/assets/svg-icon/product/add.svg" class="absolute-lt size-full" />
              <img v-else src="@/assets/svg-icon/product/add-light.svg" class="absolute-lt size-full" />
            </div>
            <div class="mt-3 h-12.5">
              <p class="mb-0.5 text-3.5 text-base_text">新建视频</p>
            </div>
          </li>
          <li v-for="item in list" :key="item.id" class="card item-ssss" :class="cardClass()">
            <NSpin content-class="pointer-events-none" :show="isLoading(item.videoStatus)">
              <template #description>{{ item.rate }}%</template>

              <div class="card-img-wraper pointer-events-none relative">
                <div
                  class="btn-warp-op pointer-events-auto absolute z-20 hidden h-full w-full select-none items-center justify-center bg-dark-700 bg-opacity-70"
                >
                  <NButton
                    v-if="isDraft(item.videoStatus)"
                    type="primary"
                    class="!text-white"
                    color="#675EE1"
                    @click="preview.show(item)"
                  >
                    继续编辑
                  </NButton>
                  <NButton
                    v-if="isDone(item.videoStatus)"
                    type="primary"
                    text
                    class="!text-white"
                    @click="preview.show(item)"
                  >
                    <SvgIcon class="text-18" icon="majesticons:play-circle"></SvgIcon>
                  </NButton>
                </div>
                <div v-if="item.coverPicture" class="absolute-lt z-10 size-full flex-center">
                  <img :src="item.coverPicture" class="object-cover" />
                </div>
                <img v-else src="@/assets/svg-icon/product/bg-3-4.svg" class="absolute-lt size-full object-cover" />
                <div class="bgitem pointer-events-none" :style="{ backgroundImage: `url(${item.coverPicture})` }"></div>

                <!-- 时长 | 草稿 -->
                <div v-if="item.videoStatus === 2" class="tips">
                  <SvgIcon class="mr-1 text-4" icon="majesticons:video-camera-line"></SvgIcon>
                  {{ item.videoDuration || 0 }}s
                </div>
                <div v-else class="tips">{{ ['草稿', '渲染中', '完成'][item.videoStatus] }}</div>
                <div
                  v-if="item.errorTip && item.videoStatus !== 2"
                  class="absolute bottom-2 right-2 z-20 z-40 h-4.5 flex-y-center rounded-1 bg-red-500/60 px-1.5 text-[11px] text-white"
                >
                  {{ item.errorTip == 'timeout' ? '渲染超时' : item.errorTip }}
                </div>
                <!-- 下载 -->
                <div class="pointer-events-auto absolute right-1 top-1 z-20 flex">
                  <NButton v-if="isDone(item.videoStatus)" class="hide-box show btn-more mr-1" @click="download(item)">
                    <SvgIcon class="text-5" icon="solar:download-minimalistic-bold"></SvgIcon>
                  </NButton>
                  <!-- 下拉选择 -->
                  <NDropdown
                    trigger="click"
                    :options="getDropdownOptions()"
                    @select="(key: any) => dropdown.onSelect(key, item)"
                  >
                    <NButton class="btn-more pointer-events-auto">
                      <SvgIcon class="text-5.5" icon="ri:more-fill"></SvgIcon>
                    </NButton>
                  </NDropdown>
                </div>
              </div>
            </NSpin>
            <div class="pointer-events-none mt-3 h-12.5">
              <p class="mb-0.5 ellipsis-text text-3.5 text-base_text">{{ item.videoName || '暂无名称' }}</p>
              <p class="text-3 text-#A4A4B0">{{ item.createTime || '2024年4月30日 08:00:09' }}</p>
            </div>
          </li>
        </ul>
      </NSpin>

      <!-- 分页组件 -->
      <div class="mt-8 flex-center">
        <NPagination
          v-model:page="pagination.page"
          v-model:page-size="pagination.pageSize"
          :page-count="Math.ceil(pagination.total / pagination.pageSize)"
          :page-sizes="[10, 20, 30]"
          show-size-picker
          :disabled="loading"
          @update:page="pagination.onChange"
          @update:page-size="pagination.onUpdatePageSize"
        />
      </div>
    </main>

    <!-- 预览弹窗 -->
    <NModal
      v-model:show="preview.visible"
      class="w-216 bg-header"
      preset="card"
      display-directive="if"
      :auto-focus="false"
      @after-leave="preview.reset"
    >
      <template #header>
        <p class="text-3.5 text-light_text">该内容由AI深度合成，请确认内容真实性</p>
      </template>
      <div style="font-size: 0" class="h-113 w-full flex-center rounded-4">
        <video controls :src="preview.row.url" class="videoClass bg-transparent"></video>
      </div>
      <div class="flex py-6">
        <div class="flex-1">
          <p class="mb-2 ellipsis-text text-4.5 text-base_text leading-normal">{{ preview.row.videoName }}</p>
          <p class="mb-6 text-3 text-light_text leading-normal">{{ preview.row.createTime }}</p>
          <p class="mb-2 ellipsis-text text-4 text-siderbar_text leading-normal">{{ preview.row.videoName }}</p>
          <p class="text-3.5 text-light_text leading-normal">
            {{ preview.row.contentText || '暂无文本' }}
          </p>
        </div>
        <div class="w-42 flex">
          <NDivider vertical class="!mx-5 !h-full !w-0.5" />
          <ul class="flex-1">
            <li class="preview-btn" @click="download(preview.row)">
              <SvgIcon class="mr-3 text-4.5 -mt-1px" icon="solar:download-minimalistic-bold"></SvgIcon>
              下载视频
            </li>
            <li class="preview-btn" @click="dropdown.onSelect('delete', preview.row)">
              <SvgIcon class="mr-3 text-4.5 -mt-1px" icon="clarity:trash-line"></SvgIcon>
              删除视频
            </li>
            <li class="preview-btn" @click="dropdown.onSelect('rename', preview.row)">
              <SvgIcon class="mr-3 text-4.5 -mt-1px" icon="tabler:pencil-cog"></SvgIcon>
              重命名
            </li>
          </ul>
        </div>
      </div>
    </NModal>

    <NModal
      v-model:show="modal.visible"
      class="w-120 bg-header"
      preset="card"
      :auto-focus="false"
      display-directive="if"
      @after-leave="modal.reset"
    >
      <template #header>
        <p class="text-5 text-base_text font-500">
          {{ modal.content }}
        </p>
      </template>
      <NInput
        v-if="modal.key === 'rename'"
        v-model:value="modal.inputValue"
        class="mb-8"
        placeholder="请输入视频名称"
        maxlength="20"
      ></NInput>
      <p v-else class="mb-6 text-3.5 text-#A4A4B0 -mt-3">
        {{ modal.subContent }}
      </p>
      <div class="flex-y-center justify-end">
        <NButton type="default" class="!mr-2 !w-22" @click="modal.visible = false">取消</NButton>
        <NButton
          v-if="modal.key === 'rename'"
          :disabled="!modal.inputValue"
          type="primary"
          class="!w-22"
          @click="modal.submit"
        >
          确定
        </NButton>
        <NButton v-else type="error" class="!w-22 !text-white" @click="modal.submit">删除</NButton>
      </div>
    </NModal>

    <!-- <PreviewModal /> -->
  </div>
</template>

<style scoped lang="scss">
$cardWidth: 223px;
$cardHeight: 432px;
$cardImgHeight: 359px;
.videoClass {
  max-height: 30rem;
}
.list {
  @apply grid gap-2 grid-cols-auto-fit p-4;
  grid-template-columns: repeat(auto-fit, $cardWidth);
  justify-content: center;

  .bgitem {
    background-position: 50%;
    background-repeat: no-repeat;
    background-size: cover;
    filter: blur(8px);
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    transform-origin: center center;
    width: 100%;
  }

  .card {
    width: $cardWidth;
    height: $cardHeight;
    @apply relative p-3 border border-transparent transition-all-300 rounded-2 cursor-pointer overflow-hidden;

    &:hover {
      .btn-warp-op {
        @apply flex;
        z-index: 20;
      }

      .hide-box.show {
        @apply opacity-100 visible;
      }
    }

    // 图片容器
    .card-img-wraper {
      width: calc(#{$cardWidth} - 24px);
      height: $cardImgHeight;
      @apply relative rounded-2 overflow-hidden;

      .hide-box {
        @apply transition-all-300 opacity-0 invisible;
      }

      // 时长
      .tips {
        @apply absolute bottom-2 z-40 left-2 h-4.5 flex-y-center rounded-1 bg-black/60 px-1.5 text-[11px] text-white;
      }

      // 下载 | 更多
      .btn-more {
        @apply h-8 w-8 px-0 bg-siderbar;
      }
    }
  }
}

// 预览
.preview-btn {
  @apply rounded-1 transition-all-300 mb-2 text-siderbar_text hover:bg-content_hover h-8 flex-y-center cursor-pointer px-2 text-3.5;
}
</style>
